بالاخره تمام شد چند روز وقت گرفت تمام اوقات فراغت این چند روز را کار کردم اولین برنامهام به زبان Go
احتمالاً شما نیز گرفتار دستیابی به ایمیلهای قدیمی خود شدهاید ایمیلهایی که از سالها پیش بایگانی شدهاند از روزهایی که با Outlook کار میکردیم تا سرویسهای مختلف تحت وب همه را در فایلهای eml نگهداشته بودم و هر بار که دنبال ایمیلی میگشتم زمان زیادی از دست میرفت
تصمیم گرفتم یک برنامه بنویسم که تمام ده هزار فایل موجود را دستهبندی کند بر اساس ایمیل فرستنده و گیرنده
زبان Go را گفتند خیلی سریع است چند سالیست که گوگل توسعه آن را آغاز کرده جایی خواندم که ده برابر سریعتر از زبانهای موجود
بسیار شبیه C و جاوا بود تصمیم گرفتم تجربه کنم خیلی دستورها را خلاصه کرده و علامتهای اضافی و بیکاربرد را پیراسته قابلیتهای جدیدی نیز افزوده جالبترین امکانش بازگرداندن چندین مقدار از یک تابع، تنها با یک دستور بازگشت (!)
اگر چه ابزاریست که بیشتر برای نوشتن Crawlerها و ابزارهای سروری استفاده میشود ولی من در اولین تجربه خود این ابزار را با آن نوشتم (نسخه غیر فشرده)
کار کردن با آن آسان است کافیست در پوشهای قرار دهید که تمام فایلهای eml در آن قرار دارد همه در یک پوشه باشند برنامه را که اجرا کنید برای هر نشانی و آدرس یک پوشه میسازد و تمام ایمیلهای مربوط به آن نشانی را در همان پوشه بر اساس تاریخ قرار میدهد نام فایلها را به تاریخ و ساعت که دسترسی آسان باشد یک علامت R یا S هم در انتها تا معلوم شود ارسالیست یا دریافتی و تمام
واقعاً سریع عمل کرد من دقیقاً 10024 عدد فایل eml داشتم از سال 2000 تا کنون با حجم حدود 5 گیگابایت از یاهو و جیمیل و هاتمیل هم در آن بود و از سرورهای محلی دیگر خروجیهایی که در تمام این سالها گرفته همه را در کمتر از 30 ثانیه دستهبندی کرد برای دسترسی به فایلها هم میتوان از ابزارهای خوبی مانند SysTools EML Viewer استفاده نمود
سورس برنامه این است:
package main
import ( "io/ioutil" "strings" "time" "os" "io" "strconv" )
var mFld,mPlc string var FldCnt,MovCnt int
func main() { bLog("\r\n===\r\nExecuting at " + time.Now().Format("2006-01-02 15:04:05") + "\r\n") mFld = "~MovedEmails " + time.Now().Format("2006-01-02") mPlc = "AllMails " + time.Now().Format("2006-01-02") files, _ := ioutil.ReadDir("./") for _, f := range files { if fName := f.Name(); fName[len(fName)-4:]==".eml" { bLog("Get File: "+fName+"\r\n") fPath := mFld + "/" + fName if _, err := os.Stat(fPath); os.IsNotExist(err) { fDate,fFrom,fTo := fRead(fName) mProc(fName,fDate + "-R",fTo) mProc(fName,fDate + "-S",fFrom) mMove(fName) MovCnt++ }else{ bLog("Aborted Because Exists!\r\n") } } } print("\nFinished: "+strconv.Itoa(MovCnt)+" Email Moved!\n") bLog("\r\nAll Folder Created: "+strconv.Itoa(FldCnt)) bLog("\r\nAll Emails Moved: "+strconv.Itoa(MovCnt)+"\r\n") bLog("\r\nFinished at " + time.Now().Format("2006-01-02 15:04:05") + "\r\n\r\n\r\n") }
func fRead(fName string)(fDate,fFrom,fTo string) { dat, err := ioutil.ReadFile(fName) check(err) fCon := string(dat) fFrom = gPart(fCon,"From") fTo = gPart(fCon,"To") fDate = gPart(fCon,"Date") bLog("From: "+fFrom+" To: "+fTo+" Date: "+fDate+"\r\n") if pos := strings.Index(fTo,","); pos>-1 { fTo = fTo[:pos] } if pos := strings.Index(fDate,","); pos>-1 { fDate = strings.TrimSpace(fDate[pos+1:]) if pos = strings.Index(fDate,"("); pos>-1 { fDate = strings.TrimSpace(fDate[:pos]) } } if fDate != "NotFound" { fDate = cDate(fDate) } return fDate, fFrom, fTo }
func check(e error) { if e != nil { //panic(e) bLog("\r\n---\r\n" + e.Error() + "\r\n---\r\n") } }
func gPart(fText,pName string)(s string) { s = "NotFound" fStr := "\n" + pName + ": " fText = "\n" + fText pos := strings.Index(fText, fStr) if pos<0 { pos = strings.Index(fText, strings.ToLower(fStr)) } if pos>-1 { npos := strings.Index(fText[pos+1:],"\n") s = fText[pos+len(fStr):pos+npos] if pos=strings.Index(s,"<"); pos>-1 && strings.Index(s[pos:],">")>0 { s = s[pos+1:pos+strings.Index(s[pos:],">")] } } return strings.TrimSpace(s) }
func cDate (t string) string { var tForm string bLog("Date Convert From: " +t) if t[len(t)-1:]!="0" { tForm = "2 Jan 2006 15:04:05 MST" }else{ tForm = "2 Jan 2006 15:04:05 -0700" if len(t)>26 { t=t[:26] } if len(t)==24 { t=t+"00" } } bLog(" By Fromat: " +tForm) dTime, err := time.Parse(tForm, t) check(err) rTime := strings.Replace(dTime.Format("2006-01-02-15:04:05"),":","",-1) bLog(" To: " +rTime+ "\r\n") return rTime }
func mProc(AslName, FileDate, FolName string) { if len(FolName)>0 { if strings.Index(FolName,"undisclosed")>-1 { return } chs := "=+\\/!&":;,\"?<" for i:=0;i<len(chs);i++ { FolName=strings.Replace(FolName,chs[i:i+1],"",-1) } FolName=strings.TrimSpace(FolName) if _, err := os.Stat(mPlc); os.IsNotExist(err) { os.Mkdir(mPlc,0777) bLog("Make Root Folder: "+mPlc+"\r\n") } if _, err := os.Stat(mPlc + "/" + FolName); os.IsNotExist(err) { os.Mkdir(mPlc + "/" + FolName,0777) print("Email: "+FolName+"\n") bLog("Make Folder: "+FolName+"\r\n") FldCnt++ } oPath := mPlc + "/" + FolName + "/" + FileDate fPath := oPath + ".eml" for i:=1;;i++ { if _, err := os.Stat(fPath); err == nil { fPath = oPath + "-" + strconv.Itoa(i) + ".eml" }else{ break } } in, err := os.Open(AslName) check(err) defer in.Close() out, err := os.Create(fPath) check(err) io.Copy(out, in) bLog("File Copied: "+AslName+" To: "+fPath+"\r\n") } }
func mMove(AslName string) { if _, err := os.Stat(mFld); os.IsNotExist(err) { os.Mkdir(mFld,0777) bLog("Make Backup Folder: "+mFld+"\r\n") } fPath := mFld + "/" + AslName if _, err := os.Stat(fPath); os.IsNotExist(err) { os.Rename(AslName,fPath) bLog("File Moved: "+AslName+"\r\n") } }
func bLog(payam string) { lName := "eml Organizer.log" f,err := os.OpenFile(lName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660) check(err) defer f.Close() f.WriteString(payam) }
میتوانید از این نشانی بردارید
یک مشکل مهم دراستفاده از زبان برنامهنویسی Go وجود دارد برای ما البته شرکت تولیدکننده آن همه IPهای داخل ایران را بسته است فیلتر کرده یعنی و نمیتوان به سادگی به کتابخانههای آن دسترسی داشت از همه بدتر وقتی از github.com سورسهای آماده را برمیداری خیلیهایشان به بستههای گوگل ارجاع دادهاند که باز نمیشوند و کامپایل نرمافزار را با مشکل روبهرو میسازند من برای نوشتن این ابزار کوچک فقط از کتابخانههای پیشفرض Go استفاده کردم
به عنوان ادیتور از میان چند برنامهای که تست نمودم Zeus را از همه راحتتر یافتم و با آن نوشتم
حالا که چه؟! اینکه اکنون میتوانم سوابق تمام مکاتبات اینترنتی خود را مرور کنم و اطلاعات مفید و قابل استفاده را باز استفاده نمایم! برچسبهای مرتبط با این نوشته:
|